package control;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.jdom.Element;

import util.CargadorXML;

import datos.ControlHoras;
import datos.Horas;
import datos.Incidencia;
import datos.Proyecto;
import datos.Tarea;

public class Cargador {

	private CargadorXML xml = null;
	private String filename = null;

	private final String NUMERO = "numero";
	private final String SIEBEL = "siebel";
	private final String NOMBRE = "nombre";
	private final String ENTRADAS = "entradas";
	private final String DESCRIPCION = "descripcion";
	private final String TIPO = "tipo";
	private final String SOLUCION = "solucion";
	private final String CONTROLHORAS = "controlHoras";
	private final String DIA = "dia";
	private final String FECHA = "fecha";
	private final String HORASANALISIS = "horasAnalisis";
	private final String HORASPRUEBAS = "horasPruebas";
	private final String FECHACREACION = "fechaCreacion";
	private final String FECHACIERRE = "fechaCierre";
	private final String ESTADO = "estado";
	private final String NOTAS = "notas";
	private final String DIRECTORIO = "directorioFicheros";
	private final String EQUIPO = "equipo";
	private final String PROBADORES = "probadores";
	private final String PROBADOR = "probador";

	private static Cargador instancia = null;

	private SimpleDateFormat df = new SimpleDateFormat("ddMMyy");

	public Cargador() {
		xml = CargadorXML.instancia();
		filename = Configuracion.get(Configuracion.DIRECTORIOXML);
	}

	public static Cargador instancia() {
		if (instancia == null) {
			instancia = new Cargador();
		}
		return instancia;
	}

	@SuppressWarnings("unchecked")
	public List<Tarea> cargar() {
		List<Tarea> lista = new ArrayList<Tarea>();

		Element root = xml.cargar(filename);
		if (root == null)
			return lista;

		Iterator i = root.getChildren("incidencia").iterator();
		while (i.hasNext()) {
			lista.add(cargarIncidencia((Element) i.next()));
		}

		i = root.getChildren("proyecto").iterator();
		while (i.hasNext()) {
			lista.add(cargarProyecto((Element) i.next()));
		}

		return lista;
	}

	private Incidencia cargarIncidencia(Element e) {
		Incidencia incidencia = new Incidencia(xml.cargarString(e, NUMERO), xml.cargarBoolean(e, SIEBEL), xml.cargarDate(e, FECHACREACION, false));
		incidencia.actualiza(Tarea.NOMBRE, xml.cargarString(e, NOMBRE));
		incidencia.actualiza(Tarea.ENTRADAS, xml.cargarString(e, ENTRADAS));
		incidencia.actualiza(Tarea.DESCRIPCION, xml.cargarString(e, DESCRIPCION));
		incidencia.actualiza(Tarea.SOLUCION, xml.cargarString(e, SOLUCION));
		incidencia.actualiza(Tarea.ESTADO, xml.cargarString(e, ESTADO));
		incidencia.actualiza(Tarea.NOTAS, xml.cargarString(e, NOTAS));
		incidencia.actualiza(Tarea.DIRECTORIO, xml.cargarString(e, DIRECTORIO));
		incidencia.actualiza(Tarea.FECHACIERRE, xml.cargarDate(e, FECHACIERRE, true));
		cargarProbadores(e.getChild(PROBADORES), incidencia.getProbadores());

		incidencia.actualiza(Incidencia.TIPO, xml.cargarString(e, TIPO));

		cargarControlHoras(e.getChild(CONTROLHORAS), incidencia.getControlHoras());

		return incidencia;
	}

	private Proyecto cargarProyecto(Element e) {
		Proyecto proyecto = new Proyecto(xml.cargarString(e, NOMBRE), xml.cargarDate(e, FECHACREACION, false));
		proyecto.actualiza(Tarea.ENTRADAS, xml.cargarString(e, ENTRADAS));
		proyecto.actualiza(Tarea.DESCRIPCION, xml.cargarString(e, DESCRIPCION));
		proyecto.actualiza(Tarea.SOLUCION, xml.cargarString(e, SOLUCION));
		proyecto.actualiza(Tarea.ESTADO, xml.cargarString(e, ESTADO));
		proyecto.actualiza(Tarea.NOTAS, xml.cargarString(e, NOTAS));
		proyecto.actualiza(Tarea.DIRECTORIO, xml.cargarString(e, DIRECTORIO));
		proyecto.actualiza(Tarea.FECHACIERRE, xml.cargarDate(e, FECHACIERRE, true));
		cargarProbadores(e.getChild(PROBADORES), proyecto.getProbadores());

		proyecto.actualiza(Proyecto.EQUIPO, xml.cargarString(e, EQUIPO));

		cargarControlHoras(e.getChild(CONTROLHORAS), proyecto.getControlHoras());

		return proyecto;
	}

	@SuppressWarnings("unchecked")
	private void cargarControlHoras(Element e, ControlHoras ch) {
		if (e == null)
			return;
		Iterator i = e.getChildren(DIA).iterator();
		while (i.hasNext()) {
			Element ed = (Element) i.next();
			String dia = ed.getAttributeValue(FECHA);
			Horas h = new Horas();
			h.fijarAnalisis(Integer.parseInt(ed.getChildText(HORASANALISIS)));
			h.fijarPruebas(Integer.parseInt(ed.getChildText(HORASPRUEBAS)));
			ch.fijarHoras(dia, h);
		}
	}

	@SuppressWarnings("unchecked")
	private void cargarProbadores(Element e, List<String> probadores) {
		if (e == null)
			return;
		Iterator i = e.getChildren(PROBADOR).iterator();
		while (i.hasNext()) {
			Element ep = (Element) i.next();
			probadores.add(ep.getText());
		}
	}

	public void guardar(List<Tarea> lista) {
		Element root = new Element("incidencias");

		Iterator<Tarea> it = lista.iterator();
		while (it.hasNext()) {
			Tarea tarea = it.next();
			if (tarea instanceof Incidencia)
				root.addContent(guardarIncidencia((Incidencia) tarea));
			if (tarea instanceof Proyecto)
				root.addContent(guardarProyecto((Proyecto) tarea));
		}

		xml.guardar(filename, root);

		return;
	}

	private Element guardarIncidencia(Incidencia incidencia) {
		Element e = new Element("incidencia");
		e.addContent(new Element(NUMERO).setText(incidencia.getNumeroseguimiento()));
		e.addContent(new Element(NOMBRE).setText(incidencia.getNombre()));
		e.addContent(new Element(ENTRADAS).setText(incidencia.getEntradas()));
		e.addContent(new Element(DESCRIPCION).setText(incidencia.getDescripcion()));
		e.addContent(new Element(SOLUCION).setText(incidencia.getSolucion()));
		e.addContent(new Element(TIPO).setText(incidencia.getTipo()));
		e.addContent(new Element(SIEBEL).setText(Boolean.toString(incidencia.isSiebel())));
		e.addContent(new Element(FECHACREACION).setText(df.format(incidencia.fechaCreacion())));
		e.addContent(new Element(FECHACIERRE).setText((incidencia.fechaCierre() == null) ? "" : df.format(incidencia.fechaCierre())));
		e.addContent(new Element(ESTADO).setText(incidencia.getEstado()));
		e.addContent(new Element(NOTAS).setText(incidencia.getNotas()));
		e.addContent(new Element(DIRECTORIO).setText(incidencia.getDirectorioFicheros()));
		e.addContent(guardarControlHoras(incidencia.getControlHoras()));
		e.addContent(guardarProbadores(incidencia.getProbadores()));
		return e;
	}

	private Element guardarProyecto(Proyecto proyecto) {
		Element e = new Element("proyecto");
		e.addContent(new Element(NOMBRE).setText(proyecto.getNombre()));
		e.addContent(new Element(EQUIPO).setText(proyecto.getEquipo()));
		e.addContent(new Element(ENTRADAS).setText(proyecto.getEntradas()));
		e.addContent(new Element(DESCRIPCION).setText(proyecto.getDescripcion()));
		e.addContent(new Element(SOLUCION).setText(proyecto.getSolucion()));
		e.addContent(new Element(FECHACREACION).setText(df.format(proyecto.fechaCreacion())));
		e.addContent(new Element(FECHACIERRE).setText((proyecto.fechaCierre() == null) ? "" : df.format(proyecto.fechaCierre())));
		e.addContent(new Element(ESTADO).setText(proyecto.getEstado()));
		e.addContent(new Element(NOTAS).setText(proyecto.getNotas()));
		e.addContent(new Element(DIRECTORIO).setText(proyecto.getDirectorioFicheros()));
		e.addContent(guardarControlHoras(proyecto.getControlHoras()));
		e.addContent(guardarProbadores(proyecto.getProbadores()));
		return e;
	}

	private Element guardarControlHoras(ControlHoras ch) {
		Element e = new Element(CONTROLHORAS);
		Iterator<String> i = ch.iterator();
		while (i.hasNext()) {
			String dia = i.next();
			Horas h = ch.horas(dia);
			Element ed = new Element(DIA);
			ed.setAttribute(FECHA, dia);
			ed.addContent(new Element(HORASANALISIS).setText(Integer.toString(h.analisis())));
			ed.addContent(new Element(HORASPRUEBAS).setText(Integer.toString(h.pruebas())));
			e.addContent(ed);
		}
		return e;
	}

	private Element guardarProbadores(List<String> probadores) {
		Element e = new Element(PROBADORES);
		Iterator<String> i = probadores.iterator();
		while (i.hasNext()) {
			e.addContent(new Element(PROBADOR).setText(i.next()));
		}
		return e;
	}
}
